package com.zyyoona7.wheelpicker.slice;

import com.zyyoona7.picker.CityPicker;
import com.zyyoona7.picker.util.SelectButton;
import com.zyyoona7.wheel.WheelView;
import com.zyyoona7.wheelpicker.ResourceTable;
import com.zyyoona7.wheelpicker.entities.CityEntity;
import com.zyyoona7.wheelpicker.utils.ParseHelper;
import com.zyyoona7.wheelpicker.utils.RandomUtil;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Picker;
import ohos.agp.components.Checkbox;
import ohos.agp.components.RadioButton;
import ohos.agp.components.RadioContainer;
import ohos.agp.components.Slider;
import ohos.agp.components.NestedScrollView;
import ohos.agp.components.Switch;
import ohos.agp.components.AbsButton;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;

import java.util.ArrayList;
import java.util.List;

/**
 * 文件描述
 *
 * @author csf
 * @since 2021-04-13
 */
public class MainAbilitySlice extends AbilitySlice {
    private static final int NUMBER = 20;
    private static final int MAXNUMBER = 100;
    private static final int TWO_HUNDRED_FIFTY = 250;
    private static final int TWO_THOUSAND = 2000;
    private static final int FIVE_HUNDRED = 500;
    private static final int FIFTY = 50;
    private static final int TEN = 10;
    private static final int THREE = 3;
    private static final int TWO = 2;
    private static final int THIRTY = 30;
    private final int num6 = 6;
    private final int num2 = 2;
    private final int num8 = 8;
    private final int num20 = 20;
    private final int num12 = 12;
    private Checkbox mSmoothCb;
    private Checkbox mSmoothCbIsBold;
    private Slider mDurationSb;
    private com.zyyoona7.picker.util.SelectButton mScrollBtn;
    private RadioContainer mAlignRg;
    private RadioButton rbLeft;
    private RadioButton rbCenter;
    private RadioButton rbRight;
    private RadioButton rbCurvedLeft;
    private RadioButton rbCurvedCenter;
    private RadioButton rbCurvedRight;
    private RadioButton rbDividerFill;
    private RadioButton rbDividerWrap;
    private com.zyyoona7.picker.util.SelectButton mSetAlignBtn;
    private com.zyyoona7.picker.util.SelectButton mSetMarginBtn;
    private Slider mMarginSb;
    private com.zyyoona7.picker.util.SelectButton mSetVisibleItemBtn;
    private Slider mVisibleItemSb;
    private Slider mLineSpacingSb;
    private com.zyyoona7.picker.util.SelectButton mSetLineSpacingBtn;
    private int markedButtonId;
    private WheelView<String> wheelView;
    private NestedScrollView nestedScrollView;
    private CityPicker cityWv;
    private Switch soundSc;
    private Slider soundVolumeSb;
    private com.zyyoona7.picker.util.SelectButton setSoundVolumeBtn;
    private Switch cyclicSc;
    private Slider paddingSb;
    private com.zyyoona7.picker.util.SelectButton setPaddingBtn;
    private Slider textSizeSb;
    private com.zyyoona7.picker.util.SelectButton setTextSizeBtn;
    private Switch dividerSc;
    private RadioContainer typeRg;
    private com.zyyoona7.picker.util.SelectButton setTypeBtn;
    private Slider heightSb;
    private com.zyyoona7.picker.util.SelectButton setHeightBtn;
    private com.zyyoona7.picker.util.SelectButton goOptionsPickerBtn;
    private com.zyyoona7.picker.util.SelectButton goCustomAttrsBtn;
    private SelectButton goDatePickerBtn;
    private String boxColor = "#FFE337BC";

    /**
     * onStart
     *
     * @param intent
     */
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        initId();
        drawNewCheckBox();
        initData();
        turnOnSound();
        setSoundEffect();
        turnOnCyclic();
        smoothDuration();
        setRandom();
        setAlign();
        setTextSize();
        setMargin();
        setVisibleItem();
        setLineSpacing();
        turnOnDivider();
        setDividerType();
        setDividerHeight();
        setDividerPadding();
        clickedListener();
    }

    /**
     * 为checkbox画新样式
     */
    private void drawNewCheckBox() {
        mSmoothCb.addDrawTask((component, canvas) -> drawCheckBox(component, canvas));
        mSmoothCb.setTouchEventListener((component, touchEvent) -> {
            component.invalidate();
            return true;
        });
        setCbIsBold();
        rbLeft.addDrawTask((component, canvas) -> drawCheckBox3(component, canvas));
        rbLeft.setCheckedStateChangedListener(new AbsButton.CheckedStateChangedListener() {
            @Override
            public void onCheckedChanged(AbsButton absButton, boolean isChecked) {
                absButton.addDrawTask((component, canvas) -> drawCheckBox2(component, canvas));
                absButton.invalidate();
            }
        });
        rbCenter.addDrawTask((component, canvas) -> drawCheckBox3(component, canvas));
        rbCenter.setCheckedStateChangedListener(new AbsButton.CheckedStateChangedListener() {
            @Override
            public void onCheckedChanged(AbsButton absButton, boolean isChecked) {
                absButton.addDrawTask((component, canvas) -> drawCheckBox2(component, canvas));
                absButton.invalidate();
            }
        });
        rbRight.addDrawTask((component, canvas) -> drawCheckBox3(component, canvas));
        rbRight.setCheckedStateChangedListener(new AbsButton.CheckedStateChangedListener() {
            @Override
            public void onCheckedChanged(AbsButton absButton, boolean isChecked) {
                absButton.addDrawTask((component, canvas) -> drawCheckBox2(component, canvas));
                absButton.invalidate();
            }
        });

        rbCurvedLeft.addDrawTask((component, canvas) -> drawCheckBox3(component, canvas));
        rbCurvedLeft.setCheckedStateChangedListener(new AbsButton.CheckedStateChangedListener() {
            @Override
            public void onCheckedChanged(AbsButton absButton, boolean isChecked) {
                absButton.addDrawTask((component, canvas) -> drawCheckBox2(component, canvas));
                absButton.invalidate();
            }
        });
        rbCurvedCenter.addDrawTask((component, canvas) -> drawCheckBox3(component, canvas));
        rbCurvedCenter.setCheckedStateChangedListener(new AbsButton.CheckedStateChangedListener() {
            @Override
            public void onCheckedChanged(AbsButton absButton, boolean isChecked) {
                absButton.addDrawTask((component, canvas) -> drawCheckBox2(component, canvas));
                absButton.invalidate();
            }
        });
        goOnDraw();
    }

    private void setCbIsBold() {
        mSmoothCbIsBold.addDrawTask((component, canvas) -> drawCheckBox(component, canvas));
        mSmoothCbIsBold.setTouchEventListener((component, touchEvent) -> {
            component.invalidate();
            return true;
        });
    }

    private void goOnDraw() {
        rbCurvedRight.addDrawTask((component, canvas) -> drawCheckBox3(component, canvas));
        rbCurvedRight.setCheckedStateChangedListener(new AbsButton.CheckedStateChangedListener() {
            @Override
            public void onCheckedChanged(AbsButton absButton, boolean isChecked) {
                absButton.addDrawTask((component, canvas) -> drawCheckBox2(component, canvas));
                absButton.invalidate();
            }
        });
        rbDividerFill.addDrawTask((component, canvas) -> drawCheckBox3(component, canvas));
        rbDividerFill.setCheckedStateChangedListener(new AbsButton.CheckedStateChangedListener() {
            @Override
            public void onCheckedChanged(AbsButton absButton, boolean isChecked) {
                absButton.addDrawTask((component, canvas) -> drawCheckBox2(component, canvas));
                absButton.invalidate();
            }
        });
        rbDividerWrap.addDrawTask((component, canvas) -> drawCheckBox3(component, canvas));
        rbDividerWrap.setCheckedStateChangedListener(new AbsButton.CheckedStateChangedListener() {
            @Override
            public void onCheckedChanged(AbsButton absButton, boolean isChecked) {
                absButton.addDrawTask((component, canvas) -> drawCheckBox2(component, canvas));
                absButton.invalidate();
            }
        });
    }

    /**
     * ID初始化
     */
    public void clickedListener() {
        goCustomAttrsBtn.setClickedListener(component -> present(new Main2AbilitySlice(), new Intent()));
        goDatePickerBtn.setClickedListener(component -> present(new MainAbility3Slice(), new Intent()));
        goOptionsPickerBtn.setClickedListener(component -> present(new MainAbility4Slice(), new Intent()));
    }

    /**
     * ID初始化
     */
    public void initId() {
        nestedScrollView = (NestedScrollView) findComponentById(ResourceTable.Id_scrollView);
        goOptionsPickerBtn = (SelectButton) findComponentById(ResourceTable.Id_btn_go_options_picker_view);
        goDatePickerBtn = (SelectButton) findComponentById(ResourceTable.Id_btn_go_date_picker_view);
        goCustomAttrsBtn = (SelectButton) findComponentById(ResourceTable.Id_btn_go_custom_attrs);
        wheelView = (WheelView<String>) findComponentById(ResourceTable.Id_wheelview);
        cityWv = (CityPicker) findComponentById(ResourceTable.Id_wv_city);
        soundSc = (Switch) findComponentById(ResourceTable.Id_sc_turn_on_sound);
        soundVolumeSb = (Slider) findComponentById(ResourceTable.Id_sb_sound_effect);
        setSoundVolumeBtn = (SelectButton) findComponentById(ResourceTable.Id_btn_set_sound_effect);
        cyclicSc = (Switch) findComponentById(ResourceTable.Id_sc_turn_on_cyclic);
        mSmoothCb = (Checkbox) findComponentById(ResourceTable.Id_cb_smooth);
        mSmoothCbIsBold = (Checkbox) findComponentById(ResourceTable.Id_cb_is_bold);
        mDurationSb = (Slider) findComponentById(ResourceTable.Id_sb_smooth_duration);
        mScrollBtn = (SelectButton) findComponentById(ResourceTable.Id_button_random);
        mAlignRg = (RadioContainer) findComponentById(ResourceTable.Id_rg_align);

        rbLeft = (RadioButton) findComponentById(ResourceTable.Id_rb_left);
        rbCenter = (RadioButton) findComponentById(ResourceTable.Id_rb_center);
        rbRight = (RadioButton) findComponentById(ResourceTable.Id_rb_right);

        rbCurvedLeft = (RadioButton) findComponentById(ResourceTable.Id_rb_curved_left);
        rbCurvedCenter = (RadioButton) findComponentById(ResourceTable.Id_rb_curved_center);
        rbCurvedRight = (RadioButton) findComponentById(ResourceTable.Id_rb_curved_right);
        rbDividerFill = (RadioButton) findComponentById(ResourceTable.Id_rb_divider_fill);
        rbDividerWrap = (RadioButton) findComponentById(ResourceTable.Id_rb_divider_wrap);

        mSetAlignBtn = (SelectButton) findComponentById(ResourceTable.Id_btn_set_align);
        textSizeSb = (Slider) findComponentById(ResourceTable.Id_sb_text_size);
        setTextSizeBtn = (SelectButton) findComponentById(ResourceTable.Id_btn_set_text_size);
        mMarginSb = (Slider) findComponentById(ResourceTable.Id_sb_margin);
        mSetMarginBtn = (SelectButton) findComponentById(ResourceTable.Id_btn_set_margin);
        mVisibleItemSb = (Slider) findComponentById(ResourceTable.Id_sb_visible_item);
        mSetVisibleItemBtn = (SelectButton) findComponentById(ResourceTable.Id_btn_set_visible_item);
        mLineSpacingSb = (Slider) findComponentById(ResourceTable.Id_sb_line_spacing);
        mSetLineSpacingBtn = (SelectButton) findComponentById(ResourceTable.Id_btn_set_line_spacing);
        dividerSc = (Switch) findComponentById(ResourceTable.Id_sc_turn_on_divider);
        typeRg = (RadioContainer) findComponentById(ResourceTable.Id_rg_divider_type);
        setTypeBtn = (SelectButton) findComponentById(ResourceTable.Id_btn_set_divider_type);
        heightSb = (Slider) findComponentById(ResourceTable.Id_sb_divider_height);
        setHeightBtn = (SelectButton) findComponentById(ResourceTable.Id_btn_set_divider_height);
        paddingSb = (Slider) findComponentById(ResourceTable.Id_sb_divider_padding);
        setPaddingBtn = (SelectButton) findComponentById(ResourceTable.Id_btn_set_divider_padding);
    }

    /**
     * 设置数据
     */
    public void initData() {
        // 解析城市列表
        List<String> list = new ArrayList<>(1);
        for (int num = 0; num < NUMBER; num++) {
            list.add(num + "日");
        }
        wheelView.setData(list);
        wheelView.setNestedScrollView(nestedScrollView);
        Picker city = (Picker) cityWv.findComponentById(ResourceTable.Id_city);
        Picker county = (Picker) cityWv.findComponentById(ResourceTable.Id_county);
        city.setVisibility(Component.HIDE);
        county.setVisibility(Component.HIDE);
    }

    /**
     * 设置是否开启滚动音效
     */
    public void turnOnSound() {
        // 经过测试 OGG 格式比 MP3 效果好
        wheelView.setSoundEffectResource("resources/rawfile/button_choose.ogg");
        soundSc.setChecked(wheelView.isSoundEffect());
        soundSc.setCheckedStateChangedListener((absButton, b) -> wheelView.setSoundEffect(b));
    }

    /**
     * 设置滚动音效音量
     */
    public void setSoundEffect() {
        soundVolumeSb.setMaxValue(MAXNUMBER);
        soundVolumeSb.setProgressValue((int) (wheelView.getPlayVolume() * MAXNUMBER));
        setSoundVolumeBtn.setClickedListener(component ->
                wheelView.setPlayVolume(soundVolumeSb.getProgress() * 1.0f / MAXNUMBER));
    }

    /**
     * 设置是否开启循环滚动效果
     */
    public void turnOnCyclic() {
        cyclicSc.setChecked(wheelView.isCyclic());
        cyclicSc.setCheckedStateChangedListener((absButton, b) -> wheelView.setCyclic(b));
    }

    /**
     * 设置平滑
     */
    public void smoothDuration() {
        mDurationSb.setProgressValue(TWO_HUNDRED_FIFTY);
        mDurationSb.setMaxValue(TWO_THOUSAND);
    }

    /**
     * 设置随机滚动到当前下标
     */
    public void setRandom() {
        mScrollBtn.setClickedListener(component -> {
            int randomPosition = new RandomUtil.SecureRandomTest().getRandom(NUMBER);
            mScrollBtn.setText("随机滚动到 " + randomPosition + " 下标");
            wheelView.setSelectedItemPosition(randomPosition, mSmoothCb.isChecked(), mDurationSb.getProgress());
        });
    }

    /**
     * 单选checkbox
     *
     * @param component
     * @param canvas
     */
    private void drawCheckBox(Component component, Canvas canvas) {
        final double height = component.getHeight();
        Paint paint = new Paint();
        paint.setColor(new Color(Color.getIntColor(boxColor)));
        paint.setStyle(Paint.Style.STROKE_STYLE);
        paint.setStrokeWidth(num6);
        canvas.drawCircle((float)(height / num2 - num8), (float) (height / num2), num20, paint);
        if (((Checkbox) component).isChecked()) {
            Paint paint2 = new Paint();
            paint2.setColor(new Color(Color.getIntColor(boxColor)));
            paint2.setStyle(Paint.Style.FILL_STYLE);
            canvas.drawCircle((float)(height / num2 - num8), (float) (height / num2), num12, paint2);
        }
    }

    /**
     * 多选checkbox
     *
     * @param component
     * @param canvas
     */
    private void drawCheckBox2(Component component, Canvas canvas) {
        final double height = component.getHeight();
        Paint paint = new Paint();
        paint.setColor(new Color(Color.getIntColor(boxColor)));
        paint.setStyle(Paint.Style.STROKE_STYLE);
        paint.setStrokeWidth(num6);
        canvas.drawCircle((float)(height / num2 - num8), (float) (height / num2), num20, paint);
        if (((AbsButton) component).isChecked()) {
            Paint paint2 = new Paint();
            paint2.setColor(new Color(Color.getIntColor(boxColor)));
            paint2.setStyle(Paint.Style.FILL_STYLE);
            canvas.drawCircle((float)(height / num2 - num8), (float) (height / num2), num12, paint2);
        }
    }

    /**
     * 多选 checkbox 外壳
     *
     * @param component
     * @param canvas
     */
    private void drawCheckBox3(Component component, Canvas canvas) {
        final double height = component.getHeight();
        Paint paint = new Paint();
        paint.setColor(new Color(Color.getIntColor(boxColor)));
        paint.setStyle(Paint.Style.STROKE_STYLE);
        paint.setStrokeWidth(num6);
        canvas.drawCircle((float)(height / num2 - num8), (float) (height / num2), num20, paint);
    }

    /**
     * 设置对齐
     */
    public void setAlign() {
        mAlignRg.setMarkChangedListener((radioContainer, i) ->
                markedButtonId = radioContainer.getComponentAt(i).getId());
        mSetAlignBtn.setClickedListener(component -> {
            int align;
            if (markedButtonId == ResourceTable.Id_rb_left) {
                align = WheelView.TEXT_ALIGN_LEFT;
            } else if (markedButtonId == ResourceTable.Id_rb_right) {
                align = WheelView.TEXT_ALIGN_RIGHT;
            } else {
                align = WheelView.TEXT_ALIGN_CENTER;
            }
            wheelView.setTextAlign(align);
        });
    }

    /**
     * 设置字体大小
     */
    public void setTextSize() {
        textSizeSb.setMaxValue(MAXNUMBER);
        textSizeSb.setProgressValue((int) wheelView.getTextSize());
        setTextSizeBtn.setClickedListener(component -> wheelView.setTextSize(textSizeSb.getProgress()));
    }

    /**
     * 设置字体左右边距
     */
    public void setMargin() {
        mMarginSb.setMaxValue(FIVE_HUNDRED);
        mMarginSb.setProgressValue(FIFTY);
        wheelView.setTextBoundaryMargin(mMarginSb.getProgress());
        mSetMarginBtn.setClickedListener(component -> wheelView.setTextBoundaryMargin(mMarginSb.getProgress()));
    }

    /**
     * 设置可见条目
     */
    public void setVisibleItem() {
        mVisibleItemSb.setMaxValue(TEN);
        mVisibleItemSb.setProgressValue(THREE);
        mSetVisibleItemBtn.setClickedListener(component -> {
            int visibleItem = mVisibleItemSb.getProgress();
            if (visibleItem < TWO) {
                mVisibleItemSb.setProgressValue(THREE);
                visibleItem = THREE;
            }
            wheelView.setVisibleItems(visibleItem);
        });
    }

    /**
     * 设置行间距
     */
    public void setLineSpacing() {
        mLineSpacingSb.setMaxValue(MAXNUMBER);
        mLineSpacingSb.setProgressValue(THIRTY);
        wheelView.setLineSpacing(THIRTY);
        mSetLineSpacingBtn.setClickedListener(component -> wheelView.setLineSpacing(mLineSpacingSb.getProgress()));
    }

    /**
     * 设置是否显示分割线
     */
    public void turnOnDivider() {
        dividerSc.setChecked(wheelView.isShowDivider());
        dividerSc.setCheckedStateChangedListener((absButton, b) -> wheelView.setShowDivider(b));
    }

    /**
     * 设置分割线类型
     */
    public void setDividerType() {
        typeRg.setMarkChangedListener((radioContainer, i) -> markedButtonId = radioContainer.getComponentAt(i).getId());
        setTypeBtn.setClickedListener(component -> {
            if (markedButtonId == ResourceTable.Id_rb_divider_fill) {
                wheelView.setDividerType(WheelView.DIVIDER_TYPE_FILL);
            } else {
                wheelView.setDividerType(WheelView.DIVIDER_TYPE_WRAP);
            }
        });
    }

    /**
     * 设置分割线高度
     */
    public void setDividerHeight() {
        heightSb.setMaxValue(NUMBER);
        heightSb.setProgressValue((int) wheelView.getDividerHeight());
        setHeightBtn.setClickedListener(component -> wheelView.setDividerHeight(heightSb.getProgress()));
    }

    /**
     * 设置分割线内间距
     */
    public void setDividerPadding() {
        paddingSb.setMaxValue(MAXNUMBER);
        paddingSb.setProgressValue((int) wheelView.getDividerPaddingForWrap());
        setPaddingBtn.setClickedListener(component -> wheelView.setDividerPaddingForWrap(paddingSb.getProgress()));
    }

    /**
     * onActive
     */
    @Override
    public void onActive() {
        super.onActive();
    }

    /**
     * onForeground
     *
     * @param intent
     */
    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }
}
